home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
prolog
/
brklyprl.lha
/
Comp
/
unravel.pl
< prev
next >
Wrap
Text File
|
1989-04-14
|
4KB
|
118 lines
/* Copyright (C) 1988, 1989 Herve' Touati, Aquarius Project, UC Berkeley */
/* Copyright Herve' Touati, Aquarius Project, UC Berkeley */
% All structures are unraveled into unify goals.
% All unify goals are of the form Var1=(Var2 or Atom or Struc),
% where Var1 is temporary or permanent and
% where Struc has only variables and atoms as arguments.
% If Var1 is permanent then so is Var2.
% Preexisting unify goals are transformed into this type.
% The structure of disjunctions remains the same (i.e.
% the operator ';' remains). Only the content is unraveled.
% Bug fix - 7/31/85:
% Handle case where the null list is an element of a list or a structure.
% - Wayne
unravel([Head|Body], [NewHead|Ravel], Perms) :-
spread(Head, NewHead, Ravel-L),
xunravel(Body, L-[], Perms), !.
xunravel([Dis|Rest], [DRavel|Ravel]-Link, Perms) :-
Dis=(_;_),
disunravel(Dis, DRavel, Perms),
xunravel(Rest, Ravel-Link, Perms).
xunravel([Goal|Rest], Ravel-Link, Perms) :-
Goal=(_=_),
varunify(Goal, Ravel-L, Perms),
xunravel(Rest, L-Link, Perms).
xunravel([Goal|Rest], Ravel-Link, Perms) :-
spread(Goal, NewGoal, Ravel-L),
L=[NewGoal|L2],
xunravel(Rest, L2-Link, Perms).
xunravel([], Link-Link, _).
disunravel((A;B), (ARavel;BRavel), Perms) :- !,
xunravel(A, ARavel-[], Perms),
disunravel(B, BRavel, Perms).
disunravel(A, ARavel, Perms) :-
xunravel(A, ARavel-[], Perms).
% Unification optimization.
% Turn the general goal 'X=Y' into a sequence
% of simpler unifications of the form
% Var1=(Var2 or Atom or Struc),
% where Var1 is a temporary or permanent variable, and
% where Struc has only atoms and variables as arguments.
varunify(X=Y, Code-Link, Perms) :-
(xvarunify(X=Y, Code-Link, Perms); Code=[fail|Link]).
% One argument is a temporary variable:
xvarunify(A=B, [A=NewB|L]-Link, Perms) :-
var(A), notin(A,Perms), !,
spread(B, NewB, L-Link).
xvarunify(A=B, [B=NewA|L]-Link, Perms) :-
var(B), notin(B,Perms), !,
spread(A, NewA, L-Link).
% One argument is a permanent variable:
xvarunify(A=B, [A=NewB|L]-Link, Perms) :-
in(A,Perms), !,
spread(B, NewB, L-Link).
xvarunify(A=B, [B=NewA|L]-Link, Perms) :-
in(B,Perms), !,
spread(A, NewA, L-Link).
% Both arguments are nonvariables:
xvarunify(A=B, Link-Link, Perms) :-
atomic(A), !, atomic(B), A=B.
xvarunify(A=B, Code-Link, Perms) :-
atomic(B), !, fail.
xvarunify(A=B, Code-Link, Perms) :- % A&B are structures
A=..[Func|ArgsA],
B=..[Func|ArgsB],
lvarunify(ArgsA, ArgsB, Code-Link, Perms).
lvarunify([A|ArgsA], [B|ArgsB], Code-Link, Perms) :-
xvarunify(A=B, Code-L, Perms), !,
lvarunify(ArgsA, ArgsB, L-Link, Perms).
lvarunify([], [], Link-Link, Perms).
% Take a (possibly nested) structure apart into
% (1) a simple structure, and (2) a series of unify goals.
% A list is considered as a structure with variable arity.
% Its cdr field is given a separate unify goal to
% accommodate the unify_cdr instruction.
spread(Var, Var, Link-Link) :- var(Var), !.
spread(Atomic, Atomic, Link-Link) :- atomic(Atomic), !.
spread(List, SimpleList, Rest-Link) :-
list(List), !,
argspread(CdrUnify, List, SimpleList, Ravel-Link),
check_cdr(CdrUnify, Ravel, Rest).
spread(Struc, SimpleStruc, Rest-Link) :-
Struc=..[Name|Args],
argspread(_, Args, VArgs, Rest-Link),
SimpleStruc=..[Name|VArgs].
check_cdr(none, Ravel, Ravel) :- !.
check_cdr(CdrUnify, Ravel, [CdrUnify|Ravel]).
argspread(none, Cdr, Cdr, Link-Link) :-
(var(Cdr);Cdr==[]), !.
argspread(T=SimpleCdr, Cdr, T, Ravel-Link) :-
nonlist(Cdr), !,
spread(Cdr, SimpleCdr, Ravel-Link).
% arg is null list
argspread(CdrUnify, [S|Args], [T|VArgs], [T=[]|L]-Link) :-
nonvar(S), S = [], !,
argspread(CdrUnify, Args, VArgs, L-Link).
argspread(CdrUnify, [A|Args], [A|VArgs], Ravel-Link) :-
(atomic(A); var(A)), !,
argspread(CdrUnify, Args, VArgs, Ravel-Link).
argspread(CdrUnify, [S|Args], [T|VArgs], Ravel-Link) :-
Ravel=[T=V|L],
spread(S, V, L-L2),
argspread(CdrUnify, Args, VArgs, L2-Link).